package it.polimi.swKnights.SWIMv2.ejb.searchEngine;

import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;

/**
 * Session Bean implementation class AdvancedSearch
 */
@Stateless
public class AdvancedSearch extends Search implements AdvancedSearchRemote
{

	/*
	 * private static final String queryAdvancedNoAbility =
	 * "SELECT ru FROM RegisteredUser ru " +
	 * "WHERE ru.name LIKE :name AND ru.surname LIKE :surname " +
	 * "AND ru.eMail LIKE :email " + "AND ru.address.city LIKE :city";
	 */

	private static final String queryRegUsersBegin = "SELECT ru FROM RegisteredUser ru "
			+ "WHERE ";

	/*
	 * private static final String queryAdvancedWithAbility =
	 * "SELECT ru FROM RegisteredUser AS ru WHERE :ability= " +
	 * "ANY(SELECT a FROM RegisteredUser u, IN (u.abilities) a WHERE u=ru) " +
	 * "AND ru.name LIKE :name" + "  AND ru.surname LIKE :surname " +
	 * "AND ru.email LIKE :email " + "AND ru.address.city LIKE :city";
	 */

	private static final String queryUrsAbilityBegin = "SELECT ru FROM RegisteredUser AS ru WHERE :ability= "
			+ "ANY(SELECT a FROM RegisteredUser u, IN (u.abilities) a WHERE u=ru) AND ";

	@Override
	public List<Map<String, String>> getListOfMapFromGeneralQuery(
			String surname, String name, String ability, String email,
			String city)
	{

		List<UserQueryResult> lstRightNameSurnEmail;
		List<UserQueryResult> lstRightAll;

		lstRightNameSurnEmail = this.getUserWithNameSurnameMail(name, surname,
				email, city);

		if (ability.length() > 0)
		{
			lstRightAll = this.findUserWithCertainAbilityAndOther(ability,
					name, surname, email, city);
		}
		else
		{
			lstRightAll = lstRightNameSurnEmail;
		}

		return this.createListOfMap(lstRightAll);

	}

	protected List<UserQueryResult> getUserWithNameSurnameMail(String name,
			String surname, String email, String city)
	{

		ResultCategory resultCategory = ResultCategory.advanced;
		String queryText;// = AdvancedSearch.queryAdvancedNoAbility;

		queryText = this.makeAdvancedQueryParametric(
				AdvancedSearch.queryRegUsersBegin, name, surname, email, city);

		return this.getUserWithNameSurnameMail(name, surname, email, city,
				queryText, resultCategory);
	}

	private String makeAdvancedQueryParametric(String beginQuery, String name,
			String surname, String email, String city)
	{

		String entityOwner = "ru";

		String namePiece = nullToOr(name, "name", entityOwner, "name");
		String surnamePiece = nullToOr(surname, "surname", entityOwner,
				"surname");
		String emailPiece = nullToOr(email, "eMail", entityOwner, "email");
		String cityPiece = nullToOr(city, "address.city", entityOwner, "city");

		return beginQuery + "" + namePiece + " AND " + surnamePiece + " AND "
				+ emailPiece + " AND " + cityPiece;

	}

	private String nullToOr(String name, String entityName, String entityOwner,
			String jpaQueryParameter)
	{

		if (name == null || name.equals(""))
		{
			// ( ru.name LIKE :name ) OR ( ru.name IS NULL )
			return "(" + entityOwner + "." + entityName + " LIKE " + ":"
					+ jpaQueryParameter + "" + " OR " + entityOwner + "."
					+ entityName + " IS NULL)";

		}
		else
		// ( ru.name LIKE :name )
		{
			return "" + entityOwner + "." + entityName + " LIKE " + ":"
					+ jpaQueryParameter + "";
		}
	}

	protected List<UserQueryResult> findUserWithCertainAbilityAndOther(
			String ability, String name, String surname, String email,
			String city)
	{
		String queryText = "";
		// query for ability
		queryText = this
				.makeAdvancedQueryParametric(
						AdvancedSearch.queryUrsAbilityBegin, name, surname,
						email, city);

		return findUserWithCertainAbilityAndOther(ability, name, surname,
				email, city, queryText, ResultCategory.advanced);

	}

}
